<html>
 <head>
  <meta charset="UTF-8">
 </head>
 <body>
  <h1 data-lake-id="p52uI" id="p52uI"><span data-lake-id="u9a6e3800" id="u9a6e3800">典型回答</span></h1>
  <p data-lake-id="u19d6e187" id="u19d6e187"><br></p>
  <p data-lake-id="uc09693b1" id="uc09693b1"><span data-lake-id="u8e7b29be" id="u8e7b29be">G1，Garbage First，是CMS的改进版，解决了CMS内存碎片、更多的内存空间等问题。总之，G1是一个先进的垃圾收集器，它可以提高系统的吞吐量，降低停顿的频率，并且可以有效管理大型堆。在JDK 9之后，G1成为了默认的垃圾回收器，主要是因为他有以下优势：</span></p>
  <p data-lake-id="uea5d18e7" id="uea5d18e7"><br></p>
  <ol list="u8c22e487">
   <li fid="u0d292603" data-lake-id="uda26f827" id="uda26f827"><strong><span data-lake-id="u06177942" id="u06177942">并发回收</span></strong><span data-lake-id="ua2a08693" id="ua2a08693">：G1能充分利用CPU、多核环境下的硬件优势，使用多个CPU（CPU或者CPU核心）来缩短Stop The World的停顿时间。部分其他收集器原本需要停顿Java线程执行的GC动作，G1收集器仍然可以通过并发的方式让Java程序继续执行。</span></li>
   <li fid="u0d292603" data-lake-id="ue6b045f1" id="ue6b045f1"><strong><span data-lake-id="u69ab3157" id="u69ab3157">分代收集</span></strong><span data-lake-id="u63c6ea2c" id="u63c6ea2c">：分代概念在G1中依然得以保留。虽然G1可以不需要其它收集器配合就能独立管理整个GC堆，但它能够采用不同的方式去处理新创建的对象和已经存活了一段时间、熬过多次GC的旧对象以获取更好的收集效果。也就是说G1可以自己管理新生代和老年代了。</span></li>
   <li fid="u0d292603" data-lake-id="u3e898aca" id="u3e898aca"><strong><span data-lake-id="u8367980d" id="u8367980d">空间整合</span></strong><span data-lake-id="u5d952bba" id="u5d952bba">：由于G1使用了独立区域（Region）概念，G1从整体来看是基于标记-整理算法实现收集，从局部（两个Region）上来看是基于标记-复制算法实现的，但无论如何，这两种算法都意味着G1运作期间不会产生内存空间碎片。</span></li>
   <li fid="u0d292603" data-lake-id="u3dc7960a" id="u3dc7960a"><strong><span data-lake-id="u05730db1" id="u05730db1">可预测的停顿</span></strong><span data-lake-id="u8544cc7c" id="u8544cc7c">：这是G1相对于CMS的另一大优势，降低停顿时间是G1和CMS共同的关注点，但G1除了追求低停顿外，还能建立可预测的停顿时间模型，能让使用者明确指定一个长度为M毫秒的时间片段内，消耗在垃圾收集上的时间不得超过N毫秒。</span></li>
   <li fid="u0d292603" data-lake-id="u470ae330" id="u470ae330"><strong><span data-lake-id="u1ff93e46" id="u1ff93e46">支持热插拔</span></strong><span data-lake-id="u9d64a61d" id="u9d64a61d">：G1可以在运行时动态调整堆的大小，以适应不同的内存需求。</span></li>
  </ol>
  <p data-lake-id="u7def91e2" id="u7def91e2"><br></p>
  <p data-lake-id="u3ba170cc" id="u3ba170cc"><span data-lake-id="udbc19fae" id="udbc19fae">与其它收集器相比，G1变化较大的是它将整个Java堆划分为多个大小相等的独立区域（Region），虽然还保留了新生代和老年代的概念，但新生代和老年代不再是物理隔离的了它们都是一部分Region（不需要连续）的集合。</span></p>
  <p data-lake-id="ua60ec473" id="ua60ec473"><br></p>
  <p data-lake-id="u57ed1481" id="u57ed1481"><span data-lake-id="u5377b4c5" id="u5377b4c5">同时，为了避免全堆扫描，G1使用了Remembered Set来管理相关的对象引用信息。当进行内存回收时，在GC根节点的枚举范围中加入Remembered Set即可保证不对全堆扫描也不会有遗漏了。</span></p>
  <p data-lake-id="u44b1abce" id="u44b1abce"><span data-lake-id="u1f103dcc" id="u1f103dcc">​</span><br></p>
  <p data-lake-id="u00731785" id="u00731785"><span data-lake-id="ucca87fc7" id="ucca87fc7">Garbage First (G1) 是一种面向大型内存环境的垃圾回收算法。因此，G1适合在以下场景中使用：</span></p>
  <ol list="u302d4482">
   <li fid="u689a8910" data-lake-id="u402eb637" id="u402eb637"><strong><span data-lake-id="ueed83340" id="ueed83340">大型内存环境</span></strong><span data-lake-id="u3abc9c44" id="u3abc9c44">：G1针对大型内存环境进行了优化，因此对于使用了大量内存的应用程序来说（超过4G），G1是一个更好的选择。</span></li>
   <li fid="u689a8910" data-lake-id="ud46e4b44" id="ud46e4b44"><strong><span data-lake-id="u52da2169" id="u52da2169">对应用程序响应时间敏感的场景</span></strong><span data-lake-id="u49b4a04c" id="u49b4a04c">：G1通过分配多线程来进行垃圾回收，以最大限度地减少回收时应用程序的暂停时间。</span></li>
   <li fid="u689a8910" data-lake-id="u2b049c54" id="u2b049c54"><strong><span data-lake-id="uc22e26ad" id="uc22e26ad">对内存使用效率敏感的场景</span></strong><span data-lake-id="u5999e598" id="u5999e598">：G1可以更好地评估哪些内存空间可以释放，以此来提高内存的利用率。</span></li>
   <li fid="u689a8910" data-lake-id="u3f20250c" id="u3f20250c"><strong><span data-lake-id="uf3909481" id="uf3909481">动态内存需求的场景</span></strong><span data-lake-id="ubcbb04d1" id="ubcbb04d1">：G1支持热插拔，可以在运行时动态调整堆的大小，以适应不同的内存需求。</span></li>
   <li fid="u689a8910" data-lake-id="u1fd5cd96" id="u1fd5cd96"><strong><span data-lake-id="u7042366e" id="u7042366e">要求回收时间具有可预测性的场景</span></strong><span data-lake-id="u6f0b64e4" id="u6f0b64e4">：G1使用固定的内存分配块来管理堆内存，这使得其在回收时间上具有更高的可预测性。</span></li>
  </ol>
  <p data-lake-id="u56feb209" id="u56feb209"><span data-lake-id="ud7db3b7f" id="ud7db3b7f">​</span><br></p>
  <p data-lake-id="u8fd17a55" id="u8fd17a55"><span data-lake-id="ue8ed87f6" id="ue8ed87f6">所以，如果应用程序需要在大型内存环境下运行，同时对内存使用效率和应用程序的响应时间敏感，那么G1是一个更好的选择。</span></p>
 </body>
</html>